﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.Assertions.Must;
using UnityEngine.UI;

public class ScoreCanvas:MonoBehaviour
{
    public Transform textsParent;
    public Transform linesParent;
    public Transform rectsParent;
    public List<Text> texts;
    public List<Image> lines;
    public List<Image> rects;
    public Image linePref;
    public Image rectPref;
    public Text textPref;

    Vector2 leftDown;

    void Awake()
    {
        var cs = GetComponentInParent<CanvasScaler>();
        leftDown = new Vector2(-cs.referenceResolution.x/2,cs.referenceResolution.y/2);
        //leftDown = new Vector2(0,0);
    }

    void Start()
    {
        linePref.gameObject.SetActive(false);
        if(rectPref)
            rectPref.gameObject.SetActive(false);
        textPref.gameObject.SetActive(false);
    }

    public Transform p1;
    public Transform p2;
    [ContextMenu("TestDrawLine")]
    void TestDrawLine()
    {
        DrawLine(p1.position.x, p1.position.y, p2.position.x, p2.position.y);
    }

    float multiX = 1f;
    float multiY = -1;

    internal void DrawLine(float x1, float y1, float x2, float y2, float lineWidth = 2)
    {
        x1 *= multiX;
        y1 *= multiY;
        x2 *= multiX;
        y2 *= multiY;

        var line = Instantiate(linePref, linesParent);
        line.gameObject.SetActive(true);
        Vector2 p1 = new Vector2(x1, y1) + leftDown;
        Vector2 p2 = new Vector2(x2, y2) + leftDown;
        Vector2 size = new Vector2((p2 - p1).magnitude, lineWidth);
        line.GetComponent<RectTransform>().anchoredPosition = (p1 + p2) / 2;
        line.GetComponent<RectTransform>().sizeDelta = size;
        Vector3 dir = p2 - p1;
        if (dir.x != 0)
        {
            float deg = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            line.transform.localRotation = Quaternion.Euler(0, 0, deg);
        }
        else
        {
            line.transform.localRotation = Quaternion.Euler(0, 0, 90);
        }
        Vector2 perpendicularVector = Vector2.Perpendicular(dir);
        line.GetComponent<RectTransform>().anchoredPosition += perpendicularVector.normalized * 0.5f *  lineWidth;

    }
    internal void DrawPath(GraphicPath topPath,float lineWdith = 2)
    {
        lineWdith *= FM_Const.GetScaleFactor();
        for (int i = 0; i < topPath.path.Count; i++)
        {
            if(i < topPath.path.Count - 1)
            {
                var p1 = topPath.path[i];
                var p2 = topPath.path[i + 1];
                DrawLine(p1.x, p1.y, p2.x, p2.y, lineWdith);
            }
        }
    }
    //internal void DrawRect(float x, float y, float width, float height, Paint font)
    internal Image DrawRect(float left, float top, float right, float bottom, Paint font)// Paint font)
    {
        return DrawRect( left, top, right, bottom,Color.black);
    }
    internal Image DrawRect(float left, float top, float right, float bottom, Color color,string name = "")
    {
        left *= multiX;
        top *= multiY;
        right *= multiX;
        bottom *= multiY;

        var img = Instantiate(rectPref, rectsParent);
        if (!string.IsNullOrEmpty(name))
            img.name = name; 
        img.gameObject.SetActive(true);
        img.color = color;
        img.GetComponent<RectTransform>().anchoredPosition = new Vector2((left + right)/2, (top + bottom)/2) + leftDown;
        img.GetComponent<RectTransform>().sizeDelta = new Vector2(Mathf.Abs(right - left), Mathf.Abs(top - bottom));

        return img;
    }
    internal Text DrawText(string text, float x, float y, Paint font,string name = "")
    {
        x *= multiX;
        y *= multiY;

        var newText = Instantiate(textPref, textsParent);
        newText.gameObject.SetActive(true);
        if(font.Typeface != null)
            newText.font = font.Typeface;
        int textSize = (int)font.TextSize;
        newText.fontSize = textSize;
        Vector2 pos = new Vector2(x /*+ newText.fontSize / 6*/, y) + leftDown;
        //Vector2 pos = new Vector2(x, y) + leftDown;
        if (text == FM_Const.TrebleClef || text == FM_Const.BassClef)
        {
            pos.x += 8;
            newText.fontSize = 50;
        }
        newText.GetComponent<RectTransform>().anchoredPosition = pos;
        text = GetScoreStr(text);
        //Debug.Log("DrawText:" + text);
        newText.text = text;
        if (!string.IsNullOrEmpty(name))
        {
            newText.name = name;
        }
        newText.color = font.Color;// (int)(10 * font.TextSize);
        return newText;
    }

    string GetScoreStr(string constStr)
    {
        if (constStr == FM_Const._1Note) return "";//
        if (constStr == FM_Const._2Note_up) return "\ue1d3";
        if (constStr == FM_Const._2Note_down) return "\ue1d4";
        if (constStr == FM_Const._4Note_up) return "♩";
        if (constStr == FM_Const._4Note_down) return "♩"; //"\ue1d6";
        if (constStr == FM_Const._8Note_up) return "♪";// "\ue1d7";
        if (constStr == FM_Const._8Note_down) return "♪"; //"\ue1d8";
        if (constStr == FM_Const._16Note_up) return "\ue1d9";
        if (constStr == FM_Const._16Note_down) return "\ue1da";
        if (constStr == FM_Const._32Note_up) return "\ue1db";
        if (constStr == FM_Const._32Note_down) return "\ue1dc";
        if (constStr == FM_Const.FillNote) return "";
        if (constStr == FM_Const.EmptyNote) return "";

        if (constStr == FM_Const.TrebleClef) return "";// "𝄞";
        if (constStr == FM_Const.BassClef) return "";// "𝄢";

        if (constStr == FM_Const.ParenthesisLeft) return "";
        if (constStr == FM_Const.ParenthesisRight) return "";
        if (constStr == FM_Const.Bracket) return "";
        if (constStr == FM_Const._2) return "";
        if (constStr == FM_Const._3) return "";
        if (constStr == FM_Const._4) return "";
        if (constStr == FM_Const._5) return "";
        if (constStr == FM_Const._6) return "";
        if (constStr == FM_Const._7) return "";
        if (constStr == FM_Const._8) return "";
        if (constStr == FM_Const._9) return "";
        if (constStr == FM_Const._2_b) return "\ue927";
        if (constStr == FM_Const._3_b) return "\ue928";
        if (constStr == FM_Const._4_b) return "\ue929";
        if (constStr == FM_Const._3_small) return "\uea54";
        if (constStr == FM_Const._5_small) return "\uea57";
        if (constStr == FM_Const.Flat) return "\ue260";
        if (constStr == FM_Const.Natural) return "♭";
        if (constStr == FM_Const.Sharp) return "♯";
        if (constStr == FM_Const.DoubleSharp) return "";
        if (constStr == FM_Const.DoubleFlat) return "\ue264";
        if (constStr == FM_Const.TripleSharp) return "\ue262 \ue263";
        if (constStr == FM_Const.TripleFlat) return "\ue266";
        if (constStr == FM_Const.Dot) return "";
        if (constStr == FM_Const.Pause_1) return "\ue4e3";
        if (constStr == FM_Const.Pause_2) return "\ue4e4";
        if (constStr == FM_Const.Pause_4) return "\ue4e5";
        if (constStr == FM_Const.Pause_8) return "\ue4e6";
        if (constStr == FM_Const.Pause_16) return "\ue4e7";
        if (constStr == FM_Const.Pause_32) return "\ue4e8";
        if (constStr == FM_Const.Tie) return "\ue551";

        return constStr;
    }

    internal void Clear()
    {
        for (int i = 0; i < textsParent.childCount; i++)
            Destroy(textsParent.GetChild(i).gameObject);
        for (int i = 0; i < linesParent.childCount; i++)
            Destroy(linesParent.GetChild(i).gameObject);
        for (int i = 0; i < rectsParent.childCount; i++)
            Destroy(rectsParent.GetChild(i).gameObject);
}
}

